package com.koron.housing.staff.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.OrderItem;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.util.StringUtils;
import com.koron.housing.apply.bean.dto.HousingStaffIntoDTO;
import com.koron.housing.apply.bean.dto.HousingStaffOutDTO;
import com.koron.housing.apply.bean.po.HousingStaffApply;
import com.koron.housing.apply.bean.query.HousingApplyQuery;
import com.koron.housing.apply.bean.vo.HousingStaffApplyVO;
import com.koron.housing.apply.bean.vo.HousingStaffIntoVO;
import com.koron.housing.apply.bean.vo.HousingStaffOutVO;
import com.koron.housing.apply.service.HousingStaffApplyService;
import com.koron.housing.apply.service.HousingStaffIntoService;
import com.koron.housing.apply.service.HousingStaffOutService;
import com.koron.housing.info.bean.po.HousingInfo;
import com.koron.housing.info.bean.po.HousingRecord;
import com.koron.housing.info.service.HousingInfoService;
import com.koron.housing.info.service.HousingRecordService;
import com.koron.housing.staff.bean.dto.HousingStaffDTO;
import com.koron.housing.staff.bean.po.HousingLease;
import com.koron.housing.staff.bean.po.HousingStaff;
import com.koron.housing.staff.bean.query.HousingStaffQuery;
import com.koron.housing.staff.bean.vo.HousingStaffVO;
import com.koron.housing.staff.mapper.HousingStaffMapper;
import com.koron.housing.staff.service.HousingLeaseService;
import com.koron.housing.staff.service.HousingStaffService;
import com.koron.housing.util.CommonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 租户信息(HousingStaff)表服务实现类
 *
 * @author jzp
 * @since 2022-02-26 11:30:35
 */
@Service("staffService")
public class HousingStaffServiceImpl implements HousingStaffService {

    @Autowired
    private HousingLeaseService leaseService;
    @Autowired
    private HousingInfoService infoService;
    @Autowired
    private HousingRecordService recordService;
    @Autowired
    private HousingStaffApplyService applyService;
    @Autowired
    private HousingStaffIntoService intoService;
    @Autowired
    private HousingStaffOutService outService;
    /**
     * 通过ID查询单条数据
     */
    @Override
    @TaskAnnotation("getById")
    public HousingStaff getById(SessionFactory factory, String id) {
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.selectById(id);
    }

    @Override
    @TaskAnnotation("getDtoById")
    public HousingStaffDTO getDtoById(SessionFactory factory, String id) {
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.selectDtoById(id);
    }

    /**
     * 每个账号只有一条租户信息
     */
    @Override
    @TaskAnnotation("getByAccount")
    public HousingStaff getByAccount(SessionFactory factory, String account) {
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.selectOneByAccount(account);
    }

    /**
     * 查询所有数据
     */
    @Override
    @TaskAnnotation("list")
    public List<HousingStaffVO> list(SessionFactory factory, HousingStaffQuery query) {
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.selectVoList(query);
    }

    @Override
    @TaskAnnotation("page")
    public PageInfo<HousingStaffVO> page(SessionFactory factory, PageQuery pageQuery, HousingStaffQuery query) {
        // 默认入住日期倒序排序
        if (CollectionUtils.isEmpty(pageQuery.getOrders())) {
            pageQuery.getOrders().add(new OrderItem("createTime", false));
        }
        pageQuery.prefixOrders("housingStaff", null);
        return HousingStaffService.super.page(factory, pageQuery, query);
    }

    /**
     * 新增数据
     */
    @Override
    @TaskAnnotation("save")
    public boolean save(SessionFactory factory, HousingStaff housingStaff) {
        // 如果没有状态，则为草稿状态
        if (StringUtils.isEmpty(housingStaff.getStatus())) {
            housingStaff.setStatus("0");
        }
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.insertOrUpdate(housingStaff) > 0;
    }

    /**
     * 修改数据
     */
    @Override
    @TaskAnnotation("update")
    public boolean update(SessionFactory factory, HousingStaff housingStaff) {
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.update(housingStaff) > 0;
    }

    @Override
    @TaskAnnotation("updateStatus")
    public boolean updateStatus(SessionFactory factory, String id, String status) {
        HousingStaff housingStaff = new HousingStaff();
        housingStaff.setId(id);
        housingStaff.setStatus(status);
        return update(factory, housingStaff);
    }

    /**
     * 通过主键删除数据
     */
    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String id) {
        HousingStaffMapper mapper = factory.getMapper(HousingStaffMapper.class);
        return mapper.hidden(id) > 0;
    }

    /**
     * 从入住信息中生成一条租户信息，且未入住
     */
    @Override
    @TaskAnnotation("notInto")
    public boolean notInto(SessionFactory factory, HousingStaffApply apply) {
        // 转化为 HousingStaff
        HousingStaff housingStaff = BeanUtil.toBean(apply, HousingStaff.class);
        // 去掉BaseBean信息
        CommonUtils.clearBaseBean(housingStaff);

        HousingStaff byAccount = getByAccount(factory, housingStaff.getAccount());
        if (byAccount != null) {
            // 租户的状态必须为未入住
            // Assert.state("0".equals(byAccount.getStatus()), "租户记录中入住状态错误：" + byAccount.getStatus());
            housingStaff.setStatus("0");
            housingStaff.setId(byAccount.getId());
            update(factory, housingStaff);
        } else {
            housingStaff.setStatus("0");
            save(factory, housingStaff);
        }

        // 2. 保存租赁信息
        HousingLease housingLease = new HousingLease();
        housingLease.setStaffId(housingStaff.getId());
        housingLease.setApplyId(apply.getId());
        housingLease.setUsageType(housingStaff.getUsageType());
        housingLease.setLayout(housingStaff.getLayout());
        housingLease.setStatus("0");
        leaseService.saveNew(factory, housingLease);
        return true;
    }

    /**
     * 从入住信息中找到一条租户信息，进行入住
     */
    @Override
    @TaskAnnotation("into")
    public boolean into(SessionFactory factory, HousingStaffIntoDTO intoDTO) {
        HousingStaff byAccount = getByAccount(factory, intoDTO.getApplyDTO().getAccount());
        Assert.notNull(byAccount, "租户记录中未找到租户信息");
        // 更新状态为已入住
        updateStatus(factory, byAccount.getId(), "1");

        // 2. 记录租赁信息
        HousingLease housingLease = new HousingLease();
        housingLease.setStaffId(byAccount.getId());
        housingLease.setHousingId(intoDTO.getHousingId());
        housingLease.setAddress(intoDTO.getAddress());
        housingLease.setRoomNum(intoDTO.getRoomNum());
        housingLease.setIntoDate(intoDTO.getIntoDate());
        housingLease.setLeaseStartTime(intoDTO.getLeaseStartTime());
        housingLease.setLeaseEndTime(intoDTO.getLeaseEndTime());
        housingLease.setStatus("1");
        HousingInfo housingInfo = infoService.getById(factory, intoDTO.getHousingId());
        housingLease.setRent(housingInfo.getRent());
        leaseService.saveNew(factory, housingLease);

        // 3. 入住后要记录租房记录
        HousingRecord housingRecord = new HousingRecord();
        housingRecord.setHousingId(intoDTO.getHousingId());
        housingRecord.setAccount(intoDTO.getApplyDTO().getAccount());
        housingRecord.setName(intoDTO.getApplyDTO().getName());
        housingRecord.setDeptId(intoDTO.getApplyDTO().getDeptId());
        housingRecord.setDeptName(intoDTO.getApplyDTO().getDeptName());
        housingRecord.setIntoDate(intoDTO.getIntoDate());
        housingRecord.setLeaseStartTime(intoDTO.getLeaseStartTime());
        housingRecord.setLeaseEndTime(intoDTO.getLeaseEndTime());
        housingRecord.setRent(housingInfo.getRent());
        recordService.saveNew(factory, housingRecord);
        // 更新房源状态
        infoService.autoStatus(factory, intoDTO.getHousingId());
        return true;
    }

    /**
     * 从退租信息中找到一条租户信息，进行退租
     */
    @Override
    @TaskAnnotation("out")
    public boolean out(SessionFactory factory, HousingStaffOutDTO outDTO) {
        // 转化为 HousingStaff
        HousingStaff housingStaff = getByAccount(factory, outDTO.getIntoDTO().getApplyDTO().getAccount());
        Assert.notNull(housingStaff, "租户记录中未找到租户信息");
        // 1. 保存主体信息
        updateStatus(factory, housingStaff.getId(), "2");

        // 2. 保存租赁信息
        HousingLease housingLease = new HousingLease();
        housingLease.setStaffId(housingStaff.getId());
        housingLease.setOutDate(outDTO.getOutDate());
        housingLease.setStatus("2");
        leaseService.saveNew(factory, housingLease);

        // 3. 退租后要记录租房记录
        HousingRecord housingRecord = new HousingRecord();
        housingRecord.setHousingId(outDTO.getIntoDTO().getHousingId());
        housingRecord.setOutDate(outDTO.getOutDate());
        recordService.saveNew(factory, housingRecord);
        // 更新房源状态
        infoService.autoStatus(factory, outDTO.getIntoDTO().getHousingId());
        return true;
    }

    @Override
    @TaskAnnotation("forceOut")
    public boolean forceOut(SessionFactory factory, String id) {
        HousingStaffDTO source = getDtoById(factory, id);
        if (source != null && source.getStatus().equals("1")) {
            // 更改租户状态为已退租
            updateStatus(factory, id, "2");

            // 查询需求申请 用户，不在已归档状态的数据，并强行归档
            HousingApplyQuery applyQuery = new HousingApplyQuery();
            applyQuery.setStatus(Arrays.asList("0", "1", "2"));
            applyQuery.setAccount(source.getAccount());
            List<HousingStaffApplyVO> list = applyService.list(factory, applyQuery);
            for (HousingStaffApplyVO housingStaffApplyVO : list) {
                applyService.updateStatus(factory, housingStaffApplyVO.getId(), "3");
            }

            // 查询入住申请 用户，不在已归档状态的数据，并强行归档
            List<HousingStaffIntoVO> list1 = intoService.list(factory, applyQuery);
            for (HousingStaffIntoVO housingStaffIntoVO : list1) {
                intoService.updateStatus(factory, housingStaffIntoVO.getId(), "4");
            }

            // 查询退租申请 用户，不在已归档状态的数据，并强行归档
            List<HousingStaffOutVO> list2 = outService.list(factory, applyQuery);
            for (HousingStaffOutVO housingStaffOutVO : list2) {
                outService.updateStatus(factory, housingStaffOutVO.getId(), "3");
            }

            // 2. 保存租赁信息
            HousingLease housingLease = new HousingLease();
            housingLease.setStaffId(id);
            housingLease.setOutDate(new Date());
            housingLease.setStatus("2");
            leaseService.saveNew(factory, housingLease);

            // 3. 退租后要记录租房记录
            source.getLeases().stream().filter(e ->"1".equals(e.getStatus())).findFirst().map(HousingLease::getHousingId).ifPresent(housingId -> {
                HousingRecord housingRecord = new HousingRecord();
                housingRecord.setHousingId(housingId);
                housingRecord.setOutDate(new Date());
                recordService.saveNew(factory, housingRecord);
                // 更新房源状态
                infoService.autoStatus(factory, housingId);
            });
            return true;
        }
        return false;
    }
}
